angular.module("services", ["ui.bootstrap", "ngFileUpload"])
.constant("constants", {
	apiPrefix: "/api",
	authTokenName: "FeastBookingAuthToken",
	feastBookingPrefix: "FeastBooking",
	hotelsStatePrefix: "FeastBooking.hotels",
	hotelsListState: "list",
	hotelsRecommondationState: "recommendation",
	hotelStatePrefix: "FeastBooking.hotel",
	createHotelState: "newHotel",
	hotelInfoState: "info",
	hotelBanquetState: "banquet",
	hotelDiscountState: "discount",
	hotelOrderState: "order",
	hotelCommentState: "commont",
	hotelCreateBanquetState: "newBanquet",
	hotelFeastState: "feast",
	hotelCreateFeastState: "newFeast",
	advertisementState: "advertisement",
	ordersState: "orders",
	orderState: "order",
	commentState: "comment",
	userState: "user",
	cashbackState: "cashback",
	username: "FeastBookingUsername",
	notificationToken: "FeastBookingNotificationToken",
	notificationState: "notifications"
})
.service("alertManager", ["$rootScope", "$timeout", function($rootScope, $timeout) {
	var timeout = 5000;
	function addAlert(level, message) {
		if(!level)
			level = "warning";
		switch(level.toLowerCase()) {
			case "success": level = "success";break;
			case "warning": level = "warning";break;
			case "danger": level = "danger";break;
			default: level = "warning"
		}
		if(message) {
			var notification = {
				level: level,
				message: message
			};
			$rootScope.alerts.push(notification);
			if(level !== "danger") {
				$timeout(function() {
					$rootScope.alerts.splice($rootScope.alerts.indexOf(notification), 1);
				}, timeout);
			}
		} else {
			console.log("No alert message!");
		}
	}
	function removeAlert(index) {
		$rootScope.alerts.splice(index, 1);
	}
	return {
		addAlert: addAlert,
		removeAlert: removeAlert
	}
}])
.service("apiService", ["$http", "$q", "$window", "constants", "Upload", function($http, $q, $window, constants, Upload) {
	function promiseFactory(method, url, headers, data, params) {
		var defered = $q.defer();
		if(!method) {
			method = "GET";
		} else {
			switch(method.toLowerCase()) {
			case "get": method = "GET";break;
			case "post": method = "POST";break;
			case "delete": method = "DELETE"; break;
			case "put": method = "PUT";break;
			default: method = "GET";
			}
		}
		headers = headers || {};
		var token = $window.localStorage[constants.authTokenName];
		if(!token)
			alert("No token.");
		headers["Authorization"] = token 
		$http({ method: method, url: url, headers: headers, data: data, params: params}).then(function(response) {
			defered.resolve(response.data);
		}, function(response) {
			defered.reject(response);
		});
		return defered.promise;
	}
	function fileUploadFactory(url, data) {
		var token = $window.localStorage[constants.authTokenName];
		if(!token)
			alert("No token.");
		var headers = {
			"Authorization": token
		};
		return Upload.upload({
			headers: headers,
			url: url,
			data: data
		});
	}
	var urlPrefix = constants.apiPrefix;
	// account api
	function signin(account) {
		return promiseFactory("POST", `${urlPrefix}/auth/token`, null, account);
	}
	// hotel api
	function getHotelList() {
		return promiseFactory("GET", `${urlPrefix}/hotels/all`);
    }
	function createHotel(hotel) {
		return promiseFactory("POST", `${urlPrefix}/hotels`, null, hotel);
	}
	function getHotelDetail(hotelId) {
		return promiseFactory("GET", `${urlPrefix}/hotels/${hotelId}`);
	}
	function updateHotelDetail(hotelDetail) {
		var hotelId = hotelDetail.id;
		return promiseFactory("PUT", `${urlPrefix}/hotels/${hotelId}`, null, hotelDetail);
	}
	function addHotelImages(hotelId, images) {
		return fileUploadFactory(`${urlPrefix}/hotels/${hotelId}/pictures`, images);
	}
	function deleteHotelImage(hotelId, names) {
		var headers = {"Content-Type": "application/json"};
		return promiseFactory("DELETE", `${urlPrefix}/hotels/${hotelId}/pictures`, headers, names);
	}
	function deleteHotels(ids) {
		var headers = {"Content-Type": "application/json"};
		return promiseFactory('DELETE', `${urlPrefix}/hotels`, headers, ids);
	}
	function createBanquet(hotelId, banquet) {
		return promiseFactory("POST", `${urlPrefix}/hotels/${hotelId}/banquet_halls`, null, banquet);
	}
	function getBanquetHall(hallId) {
		return promiseFactory("GET", `${urlPrefix}/banquet_halls/${hallId}`);
	}
	function addBanquetImages(banquetId, images) {
		return fileUploadFactory(`${urlPrefix}/banquet_halls/${banquetId}/pictures`, images);
	}
	function removeBanquetImage(banquetId, names) {
		var headers = {"Content-Type": "application/json"};
		return promiseFactory("DELETE", `${urlPrefix}/banquet_halls/${banquetId}/pictures`, headers, names);
	}
	function updateBanquet(banquet) {
		var banquetId = banquet.id;
		return promiseFactory("PUT", `${urlPrefix}/banquet_halls/${banquetId}`, null, banquet);
	}
	function createFeast(hotelId, feast) {
		return promiseFactory("POST", `${urlPrefix}/hotels/${hotelId}/feasts`, null, feast);
	}
	function getFeast(feastId) {
		return promiseFactory("GET", `${urlPrefix}/feasts/${feastId}`);
	}
	function updateFeast(feast) {
		var feastId = feast.id;
		return promiseFactory("PUT", `${urlPrefix}/feasts/${feastId}`, null, feast);
	}
	function addFeastImages(feastId, images) {
		return fileUploadFactory(`${urlPrefix}/feasts/${feastId}/pictures`, images);
	}
	function removeFeastImage(feastId, names) {
		var headers = {"Content-Type": "application/json"};
		return promiseFactory("DELETE", `${urlPrefix}/feasts/${feastId}/pictures`, headers, names);
	}
	function removeBanquet(banquetId) {
		var headers = {"Content-Type": "application/json"};
		return promiseFactory("DELETE", `${urlPrefix}/banquet_halls/${banquetId}`, headers);
	}
	function removeFeast(feastId) {
		var headers = {"Content-Type": "application/json"};
		return promiseFactory("DELETE", `${urlPrefix}/feasts/${feastId}`, headers);
	}
	function getAdsList() {
		return promiseFactory("GET", `${urlPrefix}/advertisements`);
	}
	function addAds(images) {
		return fileUploadFactory(`${urlPrefix}/advertisements`, images);
	}
	function deleteAds(id) {
		var headers = {"Content-Type": "application/json"};
		return promiseFactory("DELETE", `${urlPrefix}/advertisements/${id}`, headers);
	}
	function getRecommendationList() {
		return promiseFactory("GET", `${urlPrefix}/recommendations`);
	}
	function addRecommendation(recommendation) {
		return fileUploadFactory(`${urlPrefix}/recommendations`, recommendation);
	}
	function removeReccomndation(recommendationId) {
		var headers = {"Content-Type": "application/json"};
		return promiseFactory("DELETE", `${urlPrefix}/recommendations/${recommendationId}`, headers);
	}
	function searchOrders(params) {
		return promiseFactory("GET", `${urlPrefix}/orders` + params);
	}
	function getOrderById(id) {
		return promiseFactory("GET", `${urlPrefix}/orders/${id}`);
	}
	function approvePayment(id, state) {
		return promiseFactory("PUT", `${urlPrefix}/orders/${id}/payment?status=${state}`)
	}
	function approveContract(id, state) {
		return promiseFactory("PUT", `${urlPrefix}/orders/${id}/contract?status=${state}`);
	}
	function getComments(hotelId, params) {
		return promiseFactory("GET", `${urlPrefix}/hotels/${hotelId}/reviews`, null, null, params);
	}
	function registerAdmin(username, password) {
		return promiseFactory("POST", `${urlPrefix}/users/admin`, null, {username: username, password: password});
	}
	function registerAgent(username, password) {
		return promiseFactory("POST", `${urlPrefix}/users/manager`, null, { username: username, password: password});
	}
	function getDefaultCashback() {
		return promiseFactory("GET", `${urlPrefix}/global_cashback_strategy`);
	}
	function getCashback(orderId) {
		return promiseFactory("GET", `${urlPrefix}/orders/${orderId}/cashback_strategy`);
	}
	function saveOrderCashback(orderId, cashback) {
		return promiseFactory("PUT", `${urlPrefix}/orders/${orderId}/cashback_strategy`, null, cashback);
	}
	function gotoNextState(orderId) {
		return promiseFactory("PUT", `${urlPrefix}/orders/${orderId}/status`);
	}
	function cancelState(orderId) {
		return promiseFactory("PUT", `${urlPrefix}/orders/${orderId}/status?value=CANCELED`);
	}
	function saveDefaultCashback(cashback) {
		return promiseFactory("PUT", `${urlPrefix}/global_cashback_strategy`, null, cashback);
	}
	function getDiscount(hotelId, params) {
		return promiseFactory("GET", `${urlPrefix}/hotels/${hotelId}/discounts`, null, params);
	}
	function uploadDiscounts(hotelId, file) {
		return fileUploadFactory(`${urlPrefix}/hotels/${hotelId}/discounts`, file);
	}
	function saveNotification(notifications) {
		return promiseFactory("POST", `${urlPrefix}/notifications`, null, notifications);
	}
	function getReadNotifications(page, size) {
		return promiseFactory("GET", `${urlPrefix}/notifications?read=1&page=${page}&size=${size}`);
	};
	
    return {
    	signin: signin,
        getHotelList: getHotelList,
        createHotel: createHotel,
        getHotelDetail: getHotelDetail,
        updateHotelDetail: updateHotelDetail,
        addHotelImages: addHotelImages,
        deleteHotelImage: deleteHotelImage,
        deleteHotels: deleteHotels,
        createBanquet: createBanquet,
        getBanquetHall: getBanquetHall,
        addBanquetImages: addBanquetImages,
        removeBanquetImage: removeBanquetImage,
        updateBanquet: updateBanquet,
        createFeast: createFeast,
        getFeast: getFeast,
        updateFeast: updateFeast,
        addFeastImages: addFeastImages,
        removeFeastImage: removeFeastImage,
        removeBanquet: removeBanquet,
        removeFeast: removeFeast,
        getAdsList: getAdsList,
        addAds: addAds,
        deleteAds: deleteAds,
        getRecommendationList: getRecommendationList,
        addRecommendation: addRecommendation,
        removeReccomndation: removeReccomndation,
        searchOrders: searchOrders,
        getOrderById: getOrderById,
        approvePayment: approvePayment,
        approveContract: approveContract,
        getComments: getComments,
        registerAdmin: registerAdmin,
        getDefaultCashback: getDefaultCashback,
        getCashback: getCashback,
        saveOrderCashback: saveOrderCashback,
        gotoNextState: gotoNextState,
        cancelState: cancelState,
        saveDefaultCashback: saveDefaultCashback,
        getDiscount: getDiscount,
        uploadDiscounts: uploadDiscounts,
        registerAgent: registerAgent,
        saveNotification: saveNotification,
        getReadNotifications: getReadNotifications
    };
}])
.service("modals", ["$uibModal", function($uibModal) {
	function messageModal(title, message) {
		var modalInstance = $uibModal.open({
			template: '<div class="modal-container">'
						+ '<header class="modal-header">'
							+ '<h3>{{::title}}<span class="modal-cross" ng-click="cancel()"><span></h3>'
						+ '</header>'
						+ '<div class="modal-body">'
							+ '<span>{{::message}}</span>'
						+ '</div>'
						+ '<footer class="modal-footer">'
							+ '<button class="btn btn-primary" ng-click="confirm()">確認</button>'
							+ '<button class="btn btn-default" ng-click="cancel()">取消</button>'
						+ '</footer>'
					+ '</div>',
			controller: ['$scope', '$uibModalInstance', function($scope, $uibModalInstance) {
				$scope.title = title;
				$scope.message = message;
				$scope.confirm = function() {
					$uibModalInstance.close();
				};
				$scope.cancel = function() {
					$uibModalInstance.dismiss();
				};
			}],
			windowClass: "modal-window"
		});
		return modalInstance.result;
	}
	function addRecommendationModal(hotel) {
		var modalInstance = $uibModal.open({
			template: '<div class="modal-container">'
						+ '<div class="modal-header">'
							+ '<h3>設置推薦圖片<span class="modal-cross" ng-click="cancel()"><span></h3>'
						+ '</div>'
						+ '<div class="modal-body">'
							+ '<div>{{hotel.name}}</div>'
							+ '<div ngf-select ngf-multiple="false" ngf-change="addRecommendation($files)" class="btn btn-primary">添加圖片</div>'
						+ '</div>'
					+ '</div>',
			controller: ['$scope', '$uibModalInstance', 'alertManager', function($scope, $uibModalInstance, alertManager) {
				$scope.addRecommendation = function(file) {
					if(!file || file.length !== 1) {
						alertManager.addAlert('warning', '請添加一張圖片');
						$scope.cancel();
						return;
					}
					$uibModalInstance.close({ hotelId: hotel.id, file: file[0] });
				}
				$scope.cancel = function() {
					$uibModalInstance.dismiss();
				}
			}],
			wondowClass: "modal-window"
		});
		return modalInstance.result;
	}
	function dateRangeModal(from, to) {
		var modalInstance = $uibModal.open({
			template: '<div class="modal-container">'
						+ '<div class="modal-header">'
							+ '<h3>設置日期區間<span class="modal-cross" ng-click="cancel()"><span></h3>'
						+ '</div>'
						+ '<div class="modal-body date-range-container">'
							+ '<div class="row">'
								+ '<label class="control-label">開始日期</label>'
								+ '<div class="date-picker-wrapper">'
									+ '<input type="text" class="form-control date-picker-input" uib-datepicker-popup show-button-bar="false" ng-model="from.date" is-open="from.$$isOpen" alt-input-formats="allow" />'
					                + '<span class="input-group-btn">'
						            	+ '<button type="button" class="btn btn-default" ng-click="from.$$isOpen = !from.$$isOpen"><i class="glyphicon glyphicon-calendar"></i></button>'
									+ '</span>'
								+ '</div>'
							+ '</div>'
							+ '<div class="row">'
								+ '<label class="control-label">結束日期</label>'
								+ '<div class="date-picker-wrapper">'
									+ '<input type="text" class="form-control date-picker-input" uib-datepicker-popup show-button-bar="false" ng-model="to.date" is-open="to.$$isOpen" alt-input-formats="allow" />'
					                + '<span class="input-group-btn">'
						            	+ '<button type="button" class="btn btn-default" ng-click="to.$$isOpen = !to.$$isOpen"><i class="glyphicon glyphicon-calendar"></i></button>'
									+ '</span>'
								+ '</div>'
							+ '</div>'
						+ '</div>'
						+ '<div class="modal-footer">'
							+ '<button class="btn btn-primary" ng-disabled="!((from.date && !to.date) || (!from.date && to.date) || (from.date && to.date && from.date <= to.date))" ng-click="confirm()">確認</button>'
							+ '<button class="btn btn-default" ng-click="cancel()">取消</button>'
						+ '</div>'
					+ '</div>',
			controller: ['$scope', '$uibModalInstance', function($scope, $uibModalInstance) {
				$scope.allow = ['yyyy-MM-dd'];
				$scope.from = { $$isOpen: false, date: from};
				$scope.to = { $$isOpen: false, date: to}
				$scope.cancel = function() {
					$uibModalInstance.dismiss();
				}
				$scope.confirm = function() {
					$uibModalInstance.close({
						from: $scope.from.date, 
						to: $scope.to.date
					});
				}
			}],
			windowClass: "modal-window"
		});
		return modalInstance.result;
	}
	function imageModal(url) {
		var modalInstance = $uibModal.open({
			template: '<div class="modal-container">'
						+ '<div class="modal-header">'
							+ '<h3>图片<span class="modal-cross" ng-click="cancel()"><span></h3>'
						+ '</div>'
						+ '<div class="modal-body">'
							+ '<img ng-src="{{::url}}">'
						+ '</div>'
					+ '</div>',
			controller: ['$scope', '$uibModalInstance', function($scope, $uibModalInstance) {
				$scope.url = url;
				$scope.cancel = function() {
					$uibModalInstance.dismiss();
				}
			}],
			wondowClass: "modal-window"
		});
		return modalInstance.result;
	}
	return {
		messageModal: messageModal,
		addRecommendationModal: addRecommendationModal,
		dateRangeModal: dateRangeModal,
		imageModal: imageModal
	}
}])
.service('orderState', function() {
	function stateFactory(name, index) {
		return {
			name: name,
			index: index
		}
	}
	return [
		stateFactory("已取消", "CANCELED"),
		stateFactory("咨詢中", "CONSULTING"),
		stateFactory("已預訂", "RESERVED"),
		stateFactory("已擺酒", "FEASTED"),
		stateFactory("等待返現", "CASHBACK"),
		stateFactory("待評價", "TO_BE_REVIEWD"),
		stateFactory("結束", "DONE")
	]
})
.service('orderDateState', function() {
	function stateFactory(name, index, getRange) {
		return {
			name: name,
			index: index,
			getRange: getRange
		}
	}
	return [
		stateFactory("最近一天", 0, function() {
			var now = new Date();
			return {
				since: new Date(now - 86400000),
				until: now
			}
		}),
		stateFactory("最近一個禮拜", 1, function() {
			var now = new Date();
			return {
				since: new Date(now - 604800000),
				until: now
			}
		}),
		stateFactory("最近一個月", 2, function() {
			var now = new Date();
			return {
				since: new Date(now - 2592000000),
				until: now
			}
		}),
		stateFactory("最近一年", 3, function() {
			var now = new Date();
			return {
				since: new Date(now - 31536000000),
				until: now
			}
		}),
		stateFactory("自定義時間段", 4, function() {
			var now = new Date();
			return {
				since: new Date(now - 86400000),
				until: now
			}
		})
	]
})
.service('orderSelect', function() {
	function selectFactory(name, index) {
		return {
			name: name,
			index: index
		}
	}
	return [
	    selectFactory("全部訂單", ""),
	    selectFactory("订单号", "order_number"),
		selectFactory("酒店名", "hotel"),
		selectFactory("聯係人", "contact"),
		selectFactory("用戶名", "customer"),
		selectFactory("中介人", "recommender"),
		selectFactory("经理人", "manager"),
		selectFactory("宴會廳名", "banquet_hall")
	]
})
.service("approveState", function() {
	function approveStateFactory(name, index) {
		return {
			name: name,
			index: index
		}
	}
	return [
		approveStateFactory("未审批", "PENDING"),
		approveStateFactory("通过", "APPROVED"),
		approveStateFactory("拒绝", "DECLINED")
	]
})
.service("orderFacetGroups", ["orderState", "orderDateState", "approveState", function(orderState, orderDateState, approveState) {
	return [{
		name: "訂單狀態",
		index: "status",
		filters: angular.copy(orderState),
		$$isOpen: true
	}, {
		name: "合同审批状态",
		index: "contract_status",
		filters: angular.copy(approveState),
		$$isOpen: true
	}, {
		name: "支付审批状态",
		index: "payment_status",
		filters: angular.copy(approveState),
		$$isOpen: true
		
	}, {
		name: "訂單開始時間",
		index: "date",
		filters: angular.copy(orderDateState),
		$$isOpen: true
	}]
}])
.service("orderStateMap", function() {
	return {
		"CANCELED": 0,
		"CONSULTING": 1,
		"RESERVED": 2,
		"FEASTED": 3,
		"CASHBACK": 4,
		"TO_BE_REVIEWD": 5,
		"DONE": 6
	}
})
.service("notificationService", ["constants", function(constants) {
	var appKey = "a9d87fcaed2bcfcc393783aa";
	var flag = false;
	var charTemplate = "ABCDEFabcdef012345678";
	function getRandomStr(length) {
		var sb = "";
		if(!length || !(20 < length && length < 36))
			length = 21;
		for(var i = 0; i < length; i++) {
			var r = Math.floor(Math.random() * charTemplate.length);
			sb += charTemplate[r];
		}
		return sb;
	}
	function getInitInfo() {
		var _random_str = getRandomStr(21);
		var timestamp = (new Date().valueOf()) + "";
		var _signature = hex_md5(`appkey=${appKey}&timestamp=${timestamp}&random_str=${_random_str}&key=28c69472735863b39e2571c5`);
		return {
			appkey: appKey,
			random_str: _random_str,
			signature: _signature,
			timestamp: timestamp,
			flag: 1
		};
	}
	function getUsername() {
		var username = window.localStorage.getItem(constants.username);
		var prefix = "feastBooking_";
		return username.substring(username.indexOf(prefix) + prefix.length);
	}
	function getPassword() {
		return window.localStorage.getItem(constants.notificationToken);
	}
	return {
		getInitInfo: getInitInfo,
		appKey: appKey,
		getUsername: getUsername,
		getPassword: getPassword
	}
}])
.filter("empty", function() {
	return function(input) {
		return input? input: "暫無"
	}
})
.filter("orderState", function() {
	return function(input) {
		switch(input) {
		case "CANCELED":
			return "已取消";
		case "CONSULTING":
			return "咨詢中";
		case "RESERVED":
			return "已預訂";
		case "FEASTED":
			return "已擺酒";
		case "CASHBACK":
			return "等待返現";
		case "TO_BE_REVIEWD":
			return "待評價";
		case "DONE":
			return "結束";
		}
		return input;
	}
})
.filter("approveState", function() {
	return function(input) {
		switch(input) {
		case "PENDING": 
			return "待審批";
		case "APPROVED":
			return "通過審批";
		case "DECLINED":
			return "拒絕通過"
		}
		return input;
	}
})
.filter("limitLength", function() {
	var DefaultMaxCnt = 50;
	return function(input, maxCnt) {
		var sb = "";
		if(!maxCnt || maxCnt <= 0)
			maxCnt = DefaultMaxCnt;
		for(var i = 0; i < input.length; i++) {
			sb += input[i];
			if(i == maxCnt)
				break;
		}
		return sb;
	}
})